const xlsx = require('xlsx');
const fs = require('fs');
const path = require('path');
const { indexOf } = require('lodash');

let workBook = null;
let modules = [];

function getFilePath(fileName) {
  console.log(
    'path.resolve(__dirname, fileName)',
    path.resolve(__dirname, fileName)
  );
  return path.resolve(__dirname, fileName);
}

/**
 * 读取Excel表到JSON
 *
 * @param {string} sheetName 表名
 */
async function readExcelToJson(sheetName) {
  const workSheet = workBook.Sheets[sheetName];
  return xlsx.utils.sheet_to_json(workSheet);
}

function readXlsxFile(filePath) {
  const fileBuffer = fs.readFileSync(filePath);
  return xlsx.read(fileBuffer, { type: 'buffer' });
}

async function genRouterConfig() {
  let modulesList = [];
  let modulesNameList = [];
  const data = await readExcelToJson('路由配置');
  for (const row of data) {
    const moduleName = row['模块名'];
    // 不存在，则插入 modulesList 和 modulesNameList 中
    if (modulesNameList.indexOf(moduleName) === -1) {
      modulesNameList.push(moduleName);
      modulesList.push({
        name: moduleName,
        baseUrl: row['主路径'],
        group: row['分组'],
        routers: [],
      });
    }
    const index = modulesNameList.indexOf(moduleName);
    const route = {
      title: row['标题'],
      summary: row['简介'],
      method: row['方法'].toLowerCase(),
      url: row['接口路径'],
      name: row['接口配置表'],
    };
    modulesList[index].routers.push(route);
  }
  const result = {
    publicRoute: 'public/v1',
    modules: modulesList,
  };
  fs.writeFileSync(getFilePath('router.config.json'), JSON.stringify(result));
  modules = modulesList;
}

async function genApiConfig() {
  let result = {};
  // 每个模块下的业务表的入参和出参
  for (const module of modules) {
    const routers = module.routers;
    // 查询每个module下面的接口
    for (const router of routers) {
      const reqParentNode = router.method === 'get' ? 'query' : 'body';
      const routerName = router.name;
      // 读取对应的表
      const data = await readExcelToJson(routerName);
      if (!data) throw new Error(`路由 ${routerName} 未配置对应的参数表`);
      let index = data.findIndex((obj) => obj['父节点'] === 'res');
      if (index === -1) index = data.length;
      let argsList = [];
      let resList = [];
      for (let i = 0; i < data.length; i++) {
        const obj = data[i];
        const args = {
          父节点: i < index ? reqParentNode : obj['父节点'],
          参数名: obj['参数名'] || 'argsName',
          描述: obj['描述'] || '',
          必填: obj['必填'],
          类型: obj['类型'],
          取值范围: obj['取值范围'],
          字符长度: obj['字符长度'],
          正则: obj['正则'],
          备注: obj['备注'],
        };
        if (i < index) argsList.push(args);
        else resList.push(args);
      }
      const argsConfig = {};
      argsConfig[routerName] = {
        argsList,
        resList,
      };
      result = {
        ...result,
        ...argsConfig,
      };
    }
  }
  // 自定义类型
  const customTypeData = await readExcelToJson('自定义类型');
  let CustomTypes = [];
  for (let i = 0; i < customTypeData.length; i++) {
    const obj = customTypeData[i];
    const args = {
      父节点: obj['父节点'],
      参数名: obj['参数名'] || 'argsName',
      描述: obj['描述'] || '',
      必填: obj['必填'],
      类型: obj['类型'],
      取值范围: obj['取值范围'],
      字符长度: obj['字符长度'],
      正则: obj['正则'],
      备注: obj['备注'],
    };
    CustomTypes.push(args);
  }
  result.CustomTypes = CustomTypes;
  fs.writeFileSync(getFilePath('args.config.json'), JSON.stringify(result));
}

async function main() {
  const filePath = getFilePath('中台脚手架接口配置.xlsx');
  workBook = readXlsxFile(filePath);
  await genRouterConfig();
  await genApiConfig();
}

main();
